home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -in_the_mag- / emulation / amiga / uae-0.7.0b2 / src / debug.c < prev    next >
C/C++ Source or Header  |  1998-01-20  |  8KB  |  373 lines

  1.  /*
  2.   * UAE - The Un*x Amiga Emulator
  3.   *
  4.   * Debugger
  5.   *
  6.   * (c) 1995 Bernd Schmidt
  7.   *
  8.   */
  9.  
  10. #include "sysconfig.h"
  11. #include "sysdeps.h"
  12.  
  13. #include <ctype.h>
  14. #include <signal.h>
  15.  
  16. #include "config.h"
  17. #include "options.h"
  18. #include "threaddep/penguin.h"
  19. #include "uae.h"
  20. #include "memory.h"
  21. #include "custom.h"
  22. #include "readcpu.h"
  23. #include "newcpu.h"
  24. #include "debug.h"
  25. #include "cia.h"
  26. #include "xwin.h"
  27. #include "gui.h"
  28.  
  29. static int debugger_active = 0;
  30. static uaecptr skipaddr;
  31. static int do_skip;
  32. int debugging = 0;
  33.  
  34. void activate_debugger(void)
  35. {
  36.     do_skip = 0;
  37.     if (debugger_active)
  38.     return;
  39.     debugger_active = 1;
  40.     regs.spcflags |= SPCFLAG_BRK;
  41.     debugging = 1;
  42.     use_debugger = 1;
  43. }
  44.  
  45. int firsthist = 0;
  46. int lasthist = 0;
  47. #ifdef NEED_TO_DEBUG_BADLY
  48. struct regstruct history[MAX_HIST];
  49. union flagu historyf[MAX_HIST];
  50. #else
  51. uaecptr history[MAX_HIST];
  52. #endif
  53.  
  54. static void ignore_ws(char **c)
  55. {
  56.     while (**c && isspace(**c)) (*c)++;
  57. }
  58.  
  59. static uae_u32 readhex(char **c)
  60. {
  61.     uae_u32 val = 0;
  62.     char nc;
  63.  
  64.     ignore_ws(c);
  65.  
  66.     while (isxdigit(nc = **c)){
  67.     (*c)++;
  68.     val *= 16;
  69.     nc = toupper(nc);
  70.     if (isdigit(nc)) {
  71.         val += nc - '0';
  72.     } else {
  73.         val += nc - 'A' + 10;
  74.     }
  75.     }
  76.     return val;
  77. }
  78.  
  79. static char next_char(char **c)
  80. {
  81.     ignore_ws(c);
  82.     return *(*c)++;
  83. }
  84.  
  85. static int more_params(char **c)
  86. {
  87.     ignore_ws(c);
  88.     return (**c) != 0;
  89. }
  90.  
  91. static void dumpmem(uaecptr addr, uaecptr *nxmem, int lines)
  92. {
  93.     broken_in = 0;
  94.     for (;lines-- && !broken_in;){
  95.     int i;
  96.     printf("%08lx ", addr);
  97.     for(i=0; i< 16; i++) {
  98.         printf("%04x ", get_word(addr)); addr += 2;
  99.     }
  100.     printf("\n");
  101.     }
  102.     *nxmem = addr;
  103. }
  104.  
  105. static void foundmod (uae_u32 ptr, char *type)
  106. {
  107.     char name[21];
  108.     uae_u8 *ptr2 = chipmemory + ptr;
  109.     int i,length;
  110.  
  111.     printf ("Found possible %s module at 0x%lx.\n", type, ptr);
  112.     memcpy (name, ptr2, 20);
  113.     name[20] = '\0';
  114.  
  115.     /* Browse playlist */
  116.     length = 0;
  117.     for (i = 0x3b8; i < 0x438; i++)
  118.     if (ptr2[i] > length)
  119.         length = ptr2[i];
  120.  
  121.     length = (length+1)*1024 + 0x43c;
  122.  
  123.     /* Add sample lengths */
  124.     ptr2 += 0x2A;
  125.     for(i = 0; i < 31; i++, ptr2 += 30)
  126.     length += 2*((ptr2[0]<<8)+ptr2[1]);
  127.     
  128.     printf("Name \"%s\", Length 0x%lx bytes.\n", name, length);
  129. }
  130.  
  131. static void modulesearch(void)
  132. {
  133.     uae_u8 *p = get_real_address (0);
  134.     uae_u32 ptr;
  135.  
  136.     for (ptr = 0; ptr < chipmem_size - 40; ptr += 2, p += 2) {
  137.     /* Check for Mahoney & Kaktus */
  138.     /* Anyone got the format of old 15 Sample (SoundTracker)modules? */
  139.     if (ptr >= 0x438 && p[0] == 'M' && p[1] == '.' && p[2] == 'K' && p[3] == '.')
  140.         foundmod (ptr - 0x438, "ProTracker (31 samples)");
  141.  
  142.     if (ptr >= 0x438 && p[0] == 'F' && p[1] == 'L' && p[2] == 'T' && p[3] == '4')
  143.         foundmod (ptr - 0x438, "Startrekker");
  144.  
  145.     if (strncmp ((char *)p, "SMOD", 4) == 0) {
  146.         printf ("Found possible FutureComposer 1.3 module at 0x%lx, length unknown.\n", ptr);
  147.     }
  148.     if (strncmp ((char *)p, "FC14", 4) == 0) {
  149.         printf ("Found possible FutureComposer 1.4 module at 0x%lx, length unknown.\n", ptr);
  150.     }
  151.     if (p[0] == 0x48 && p[1] == 0xe7 && p[4] == 0x61 && p[5] == 0
  152.         && p[8] == 0x4c && p[9] == 0xdf && p[12] == 0x4e && p[13] == 0x75
  153.         && p[14] == 0x48 && p[15] == 0xe7 && p[18] == 0x61 && p[19] == 0
  154.         && p[22] == 0x4c && p[23] == 0xdf && p[26] == 0x4e && p[27] == 0x75) {
  155.         printf ("Found possible Whittaker module at 0x%lx, length unknown.\n", ptr);
  156.     }
  157.     if (p[4] == 0x41 && p[5] == 0xFA) {
  158.         int i;
  159.  
  160.         for (i = 0; i < 0x240; i += 2)
  161.         if (p[i] == 0xE7 && p[i + 1] == 0x42 && p[i + 2] == 0x41 && p[i + 3] == 0xFA)
  162.             break;
  163.         if (i < 0x240) {
  164.         uae_u8 *p2 = p + i + 4;
  165.         for (i = 0; i < 0x30; i += 2)
  166.             if (p2[i] == 0xD1 && p2[i + 1] == 0xFA) {
  167.             printf ("Found possible MarkII module at %lx, length unknown.\n", ptr);
  168.             }
  169.         }
  170.         
  171.     }
  172.     }
  173. }
  174.  
  175. void debug(void)
  176. {
  177.     char input[80],c;
  178.     uaecptr nextpc,nxdis,nxmem;
  179.  
  180.     bogusframe = 1;
  181.  
  182.     if (do_skip && (m68k_getpc() != skipaddr/* || regs.a[0] != 0x1e558*/)) {
  183.     regs.spcflags |= SPCFLAG_BRK;
  184.     return;
  185.     }
  186.     do_skip = 0;
  187.  
  188. #ifdef NEED_TO_DEBUG_BADLY
  189.     history[lasthist] = regs;
  190.     historyf[lasthist] = regflags;
  191. #else
  192.     history[lasthist] = m68k_getpc();
  193. #endif
  194.     if (++lasthist == MAX_HIST) lasthist = 0;
  195.     if (lasthist == firsthist) {
  196.     if (++firsthist == MAX_HIST) firsthist = 0;
  197.     }
  198.  
  199.     m68k_dumpstate(&nextpc);
  200.     nxdis = nextpc; nxmem = 0;
  201.  
  202.     for(;;){
  203.     char cmd,*inptr;
  204.  
  205.     printf(">");
  206.     fflush (stdout);
  207.     if (fgets(input, 80, stdin) == 0)
  208.         return;
  209.     inptr = input;
  210.     cmd = next_char(&inptr);
  211.     switch(cmd){
  212.      case 'c': dumpcia(); dumpcustom(); break;
  213.      case 'r': m68k_dumpstate(&nextpc); break;
  214.      case 'M': modulesearch(); break;
  215.      case 'S':
  216.         {
  217.         uae_u8 *memp;
  218.         uae_u32 src, len;
  219.         char *name;
  220.         FILE *fp;
  221.  
  222.         if (!more_params (&inptr))
  223.             goto S_argh;
  224.  
  225.         name = inptr;
  226.         while (*inptr != '\0' && !isspace (*inptr))
  227.             inptr++;
  228.         if (!isspace (*inptr))
  229.             goto S_argh;
  230.  
  231.         *inptr = '\0';
  232.         inptr++;
  233.         if (!more_params (&inptr))
  234.             goto S_argh;
  235.         src = readhex (&inptr);
  236.         if (!more_params (&inptr))
  237.             goto S_argh;
  238.         len = readhex (&inptr);
  239.         if (! valid_address (src, len)) {
  240.             printf ("Invalid memory block\n");
  241.             break;
  242.         }
  243.         memp = get_real_address (src);
  244.         fp = fopen (name, "w");
  245.         if (fp == NULL) {
  246.             printf ("Couldn't open file\n");
  247.             break;
  248.         }
  249.         if (fwrite (memp, 1, len, fp) != len) {
  250.             printf ("Error writing file\n");
  251.         }
  252.         fclose (fp);
  253.         break;
  254.  
  255.         S_argh:
  256.         printf ("S command needs more arguments!\n");
  257.         break;
  258.         }
  259.      case 'd':
  260.         {
  261.         uae_u32 daddr;
  262.         int count;
  263.  
  264.         if (more_params(&inptr))
  265.             daddr = readhex(&inptr);
  266.         else
  267.             daddr = nxdis;
  268.         if (more_params(&inptr))
  269.             count = readhex(&inptr);
  270.         else
  271.             count = 10;
  272.         m68k_disasm(daddr, &nxdis, count);
  273.         }
  274.         break;
  275.      case 't': regs.spcflags |= SPCFLAG_BRK; return;
  276.      case 'z':
  277.         skipaddr = nextpc;
  278.         do_skip = 1;
  279.         regs.spcflags |= SPCFLAG_BRK;
  280.         return;
  281.  
  282.      case 'f':
  283.         skipaddr = readhex(&inptr);
  284.         do_skip = 1;
  285.         regs.spcflags |= SPCFLAG_BRK;
  286.         return;
  287.  
  288.      case 'q': uae_quit();
  289.         debugger_active = 0;
  290.         debugging = 0;
  291.         return;
  292.  
  293.      case 'g':
  294.         if (more_params (&inptr))
  295.         m68k_setpc (readhex (&inptr));
  296.         debugger_active = 0;
  297.         debugging = 0;
  298.         return;
  299.  
  300.      case 'H':
  301.         {
  302.         int count;
  303.         int temp;
  304. #ifdef NEED_TO_DEBUG_BADLY
  305.         struct regstruct save_regs = regs;
  306.         union flagu save_flags = regflags;
  307. #endif
  308.  
  309.         if (more_params(&inptr))
  310.             count = readhex(&inptr);
  311.         else
  312.             count = 10;
  313.         if (count < 0)
  314.             break;
  315.         temp = lasthist;
  316.         while (count-- > 0 && temp != firsthist) {
  317.             if (temp == 0) temp = MAX_HIST-1; else temp--;
  318.         }
  319.         while (temp != lasthist) {
  320. #ifdef NEED_TO_DEBUG_BADLY
  321.             regs = history[temp];
  322.             regflags = historyf[temp];
  323.             m68k_dumpstate(NULL);
  324. #else
  325.             m68k_disasm(history[temp], NULL, 1);
  326. #endif
  327.             if (++temp == MAX_HIST) temp = 0;
  328.         }
  329. #ifdef NEED_TO_DEBUG_BADLY
  330.         regs = save_regs;
  331.         regflags = save_flags;
  332. #endif
  333.         }
  334.         break;
  335.      case 'm':
  336.         {
  337.         uae_u32 maddr; int lines;
  338.         if (more_params(&inptr))
  339.             maddr = readhex(&inptr);
  340.         else
  341.             maddr = nxmem;
  342.         if (more_params(&inptr))
  343.             lines = readhex(&inptr);
  344.         else
  345.             lines = 16;
  346.         dumpmem(maddr, &nxmem, lines);
  347.         }
  348.         break;
  349.       case 'h':
  350.       case '?':
  351.         {
  352.         printf ("          HELP for UAE Debugger\n");
  353.         printf ("         -----------------------\n\n");
  354.         printf ("  g: <address>          Start execution at the current address or <address>\n");
  355.         printf ("  c:                    Dump state of the CIA and custom chips\n");
  356.         printf ("  r:                    Dump state of the CPU\n");
  357.         printf ("  m <address> <lines>:  Memory dump starting at <address>\n");
  358.         printf ("  d <address> <lines>:  Disassembly starting at <address>\n");
  359.         printf ("  t:                    Step one instruction\n");
  360.         printf ("  z:                    Step through one instruction - useful for JSR, DBRA etc\n");
  361.         printf ("  f <address>:          Step forward until PC == <address>\n");
  362.         printf ("  H <count>:            Show PC history <count> instructions\n");
  363.         printf ("  M:                    Search for *Tracker sound modules\n");
  364.         printf ("  S <file> <addr> <n>:  Save a block of Amiga memory\n");
  365.         printf ("  h,?:                  Show this help page\n");
  366.         printf ("  q:                    Quit the emulator. You don't want to use this command.\n\n");
  367.         }
  368.         break;
  369.  
  370.     }
  371.     }
  372. }
  373.